﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Marbles.Core.Authentication;
using Marbles.Core.Content.Sites;
using System.Web.UI;
using Marbles.Core.Filters;
using System.IO;
using System.Web.UI.HtmlControls;
using System.Web;
using Marbles.Core.Handlers;
using Marbles.Core.Content.Pages;
using Marbles.Core.Content.Analytics;
using System.Web.UI.WebControls;
using Marbles.Core.Content.CDN;
using Marbles.Core.Settings;

namespace Marbles.Core.Pages
{
    public class Page : System.Web.UI.Page
    {
        public string PageName
        {
            get
            {
                object obj = null;
                if (SettingsManager.TrustLevel == AspNetHostingPermissionLevel.Medium)
                {
                    if (Request.Params["id"] != null) { obj = Request.Params["id"].Trim().ToLower(); }
                }
                else { obj = Context.Items["Name"]; }

                return (obj == null) ? "Default" : obj.ToString();
            }
        }

        public HtmlHead MasterHeader
        {
            get
            {
                if (this.Master == null) { return this.Header; }
                HtmlHead head = this.Master.FindControl("head") as HtmlHead;
                if (head == null) { return this.Header; }
                return head;
            }
        }

        public SiteDefinition CurrentWeb
        {
            get { return SiteDefinition.GetCurrent(); }
        }

        public PageDefinition CurrentPage
        {
            get
            {
                PageDefinition def = new PageDefinition(this.CurrentWeb.SiteName, this.PageName);
                bool IsAdmin = (this.AuthenticationProvider.CurrentToken == null) ? false : (this.AuthenticationProvider.CurrentToken.IsAdministrator || this.AuthenticationProvider.CurrentToken.IsRoot || this.AuthenticationProvider.CurrentToken.IsEditor);
                if (def.Published) { return def; }
                if (IsAdmin) { return def; }
                return null;
            }
        }

        public Marbles.Core.Authentication.AuthenticationProvider AuthenticationProvider
        {
            get { return Marbles.Core.Authentication.AuthenticationProvider.CreateProviderInstance(); }
        }

        public bool IsEditor
        {
            get
            {
                IToken token = this.AuthenticationProvider.CurrentToken;
                return (token == null) ? false : token.IsEditor;
            }
        }

        public bool IsAdministrator
        {
            get
            {
                IToken token = this.AuthenticationProvider.CurrentToken;
                return (token == null) ? false : token.IsAdministrator;
            }
        }

        public bool isViewer
        {
            get
            {
                IToken token = this.AuthenticationProvider.CurrentToken;
                return (token == null) ? true : token.IsViewer;
            }
        }

        public string Username
        {
            get
            {
                IToken token = this.AuthenticationProvider.CurrentToken;
                return (token == null) ? "" : token.Username;
            }
        }

        public string Html { get { return GetPageHtml(this); } }


        protected static string GetPageHtml(Page page)
        {
            StringWriter sw = new StringWriter();
            HtmlTextWriter writer = new HtmlTextWriter(sw);
            page.RenderControl(writer);
            sw.Close();
            return sw.ToString();
        }

        protected override PageStatePersister PageStatePersister
        {
            get
            {
                string value = Settings.SettingsManager.PageStatePersister;
                switch (value.ToLower())
                {
                    case "gzip":
                        return new CompressedPageStatePersister(this, CompressionMethod.GZip);
                    case "deflate":
                        return new CompressedPageStatePersister(this, CompressionMethod.Deflate);
                }
                return base.PageStatePersister;
            }
        }

        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            System.IO.StringWriter stringWriter = new System.IO.StringWriter();
            HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
            base.Render(htmlWriter);
            string html = stringWriter.ToString();
            int StartPoint = html.IndexOf("<input type=\"hidden\" name=\"__VSTATE\"");
            if (StartPoint >= 0)
            {
                int EndPoint = html.IndexOf("/>", StartPoint) + 2;
                string viewstateInput = html.Substring(StartPoint, EndPoint - StartPoint);
                html = html.Remove(StartPoint, EndPoint - StartPoint);
                int FormEndStart = html.IndexOf("</form>") - 1;
                if (FormEndStart >= 0)
                {
                    html = html.Insert(FormEndStart, viewstateInput);
                }
            }

            StartPoint = html.IndexOf("<input type=\"hidden\" name=\"__VIEWSTATE\"");
            if (StartPoint >= 0)
            {
                int EndPoint = html.IndexOf("/>", StartPoint) + 2;
                string viewstateInput = html.Substring(StartPoint, EndPoint - StartPoint);
                html = html.Remove(StartPoint, EndPoint - StartPoint);
                int FormEndStart = html.IndexOf("</form>") - 1;
                if (FormEndStart >= 0)
                {
                    html = html.Insert(FormEndStart, viewstateInput);
                }
            } 
            
            writer.Write(html);
        }

        public void RegisterClientScriptHeaderInclude(string key, string url)
        {
            if (this.MasterHeader == null) { return; }
            if (this.MasterHeader.FindControl(key) != null) { return; }
            LiteralControl control = new LiteralControl();
            control.ID = key;
            control.Text = string.Format("<script language=\"javascript\" type=\"text/javascript\" src=\"{0}\" ></script>", url);
            this.MasterHeader.Controls.Add(control);
        }

        public void AddStyleSheetInclude(string key, string url)
        {
            if (this.MasterHeader == null) { return; }
            if (this.MasterHeader.FindControl(key) != null) { return; }
            LiteralControl control = new LiteralControl();
            control.ID = key;
            control.Text = string.Format("<link rel=\"Stylesheet\" type=\"text/css\" href=\"{0}\" />", url);
            this.MasterHeader.Controls.Add(control);
        }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            if (string.IsNullOrEmpty(this.CurrentWeb.AnalyticsEngine)) { return; }
            CreateAnalyticsControl();
        }

        protected virtual void CreateAnalyticsControl()
        {
            WebControl analyticsControl = AnalyticsEngine.GetEngine(this.CurrentWeb.AnalyticsEngine, this.CurrentWeb.AnalyticsSettings);
            if (analyticsControl != null)
            {
                this.Form.Controls.Add(analyticsControl);
            }
        }

        public void AddMetaTag(string id, string HttpEquiv, string content)
        {
            this.AddMetaTag(id, HttpEquiv, content, "");
        }

        public void AddMetaTag(string id, string HttpEquiv, string content, string name)
        {
            if (this.MasterHeader == null) { return; }
            HtmlMeta meta = new HtmlMeta();
            meta.ID = id;
            if (string.IsNullOrEmpty(name))
            {
                meta.HttpEquiv = HttpEquiv;
            }
            else
            {
                meta.Name = name;
            }

            meta.Content = content;
            this.MasterHeader.Controls.Add(meta);
        }

        public void AddRSSFeedDiscoveryTag(string id, string title, string url)
        {
            if (this.MasterHeader == null) { return; }
            if (this.MasterHeader.FindControl(id) != null) { return; }
            LiteralControl control = new LiteralControl();
            control.ID = id;
            control.Text = string.Format("<link rel=\"alternate\" type=\"{0}\" title=\"{1}\" href=\"{2}\" /> ", RSSFeed.ContentType, Title, url);
            this.MasterHeader.Controls.Add(control);
        }

        public void AddAtomFeedDiscoveryTag(string id, string title, string url)
        {
            if (this.MasterHeader == null) { return; }
            if (this.MasterHeader.FindControl(id) != null) { return; }
            LiteralControl control = new LiteralControl();
            control.ID = id;
            control.Text = string.Format("<link rel=\"alternate\" type=\"{0}\" title=\"{1}\" href=\"{2}\" /> ", AtomFeed.ContentType, Title, url);
            this.MasterHeader.Controls.Add(control);
        }

        protected override void OnPreInit(EventArgs e)
        {
            if (CurrentWeb == null) { return; }
            if (String.IsNullOrEmpty(CurrentWeb.Host)) { return; }
            string path = Server.MapPath(CurrentWeb.TemplateDirectory);
            string filename = string.Empty;
            filename = CurrentWeb.TemplateDirectory + CurrentWeb.Host + ".master";

            if (!Directory.Exists(path)) { Directory.CreateDirectory(path); }
            if (CurrentPage != null)
            {
                if (string.IsNullOrEmpty(CurrentPage.TemplateName))
                {
                    filename = CurrentWeb.TemplateDirectory + CurrentWeb.Host + ".master";
                }
                else
                {
                    filename = CurrentWeb.TemplateDirectory + CurrentPage.TemplateName + ".master";
                }
            }

            if (File.Exists(Server.MapPath(filename))) { this.MasterPageFile = filename; }

            if (CurrentPage != null)
            {
                if (CurrentPage.ApplyTheme)
                {
                    if (!string.IsNullOrEmpty(CurrentWeb.Theme))
                    {
                        this.Theme = string.Empty;
                        string fullpath = HttpContext.Current.Server.MapPath(string.Format("~/App_Themes/{0}", CurrentWeb.Theme));
                        if (System.IO.Directory.Exists(fullpath)) { this.Theme = CurrentWeb.Theme; }
                    }
                }
            }

        }

        protected override void OnLoad(EventArgs e)
        {
            CDNParser cdn = new CDNParser();
            RegisterClientScriptHeaderInclude("marblesApplication", Resources.ResourceHandler.GetApplicationJavascript(this));
            cdn.RegisterHeaderIncludes(this);
            base.OnLoad(e);
        }

    }
}
